﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Common.Logging;

using WorkStation.Frameworks.EasyBus;
using WorkStation.Frameworks.EasyBus.Handles;
using WorkStation.Frameworks.EasyBus.Repositories;
using WorkStation.Frameworks.EasyBus.Pipeline;
using WorkStation.Frameworks.EasyBus.Plugins;
using WorkStation.Frameworks.EasyBus.Pipeline.Handles;
using WorkStation.Frameworks.EasyBus.MessageQueue;

namespace WorkStation.Frameworks.EasyBus
{
    /// <summary>
    /// 总线数据管理接口
    /// </summary>
    public interface IBusDataManager
    {
        /// <summary>
        /// 发送消息通道
        /// </summary>
        IPipeline SendMessagePipeline { get; set; }

        /// <summary>
        /// 总线事件管道
        /// </summary>
        IPipeline BusEventPipeline { get; set; }

        /// <summary>
        /// 监听器服务对象
        /// </summary>
        IServer Server { get; set; }

        /// <summary>
        /// 总线所在服务器IP
        /// </summary>
        string Ip { get; set; }

        /// <summary>
        /// 注册中心仓储组件
        /// </summary>
        IRegisterCenterRepository RegisterCenterRepository { get; set; }

        /// <summary>
        /// 历史记录中心仓储组件
        /// </summary>
        IHistoryCenterRepository HistoryCenterRepository { get; set; }
    }

    /// <summary>
    /// 总线接口
    /// </summary>
    public interface IBus : IDisposable
    {
        event Action<BusActionContext, FailHandleResult> OnPublishFail;
        event Action<BusActionContext, SuccessHandleResult> OnPublishSuccess;
        event Action<BusActionContext> OnPublishBefore;
        event Action<BusActionContext, IEnumerable<HandleResult>> OnPublishAfter;

        event Action<BusActionContext, FailHandleResult> OnProcessFail;
        event Action<BusActionContext, SuccessHandleResult> OnProcessSuccess;
        event Action<BusActionContext> OnProcessBefore;
        event Action<BusActionContext, IEnumerable<HandleResult>> OnProcessAfter;

        event Action<BusActionContext, FailHandleResult> OnEventFail;

        event Action<Exception> OnListenException;

        string Name { get; set; }

        /// <summary>
        /// 负载节点名称
        /// </summary>
        string NodeName { get; set; }

        List<IBusPlugin> Plugins { get; set; }

        List<IConfigProvider> ConfigProvider { get; set; }

        /// <summary>
        /// 数据
        /// </summary>
        Dictionary<string, object> DataBag { get; set; }

        /// <summary>
        /// 日志
        /// </summary>
        ILog Logger { get; set; }

        /// <summary>
        /// 订阅发布处理器
        /// </summary>
        /// <param name="routeKey">路由关键字</param>
        /// <param name="handle">处理器对象</param>
        /// <returns></returns>
        IBus Subscribe(string routeKey, IHandle handle);

        /// <summary>
        /// 设置监听器
        /// </summary>
        /// <param name="name">监听器名称</param>
        /// <param name="endpoint">监听的终结点名称</param>
        /// <param name="processThreadCount">监听器线程数</param>
        /// <returns></returns>
        IBus Listen(string name, IEndpoint endpoint, int processThreadCount = 1);

        /// <summary>
        /// 设置监听器处理内容
        /// </summary>
        /// <param name="name">监听器名称</param>
        /// <param name="routeKey">路由关键字</param>
        /// <param name="handle">处理器</param>
        /// <returns></returns>
        IBus SetListenerProcess(string name, string routeKey, ProcessHandle handle);

        /// <summary>
        /// 发布消息
        /// </summary>
        /// <param name="msg">消息对象</param>
        /// <returns>发布结果</returns>
        IEnumerable<HandleResult> Publish(object msg);

        /// <summary>
        /// 启动监听
        /// </summary>
        /// <returns></returns>
        IBus Start();

        /// <summary>
        /// 安装监听服务器对象（还可以从IOC中添加，都没有默认使用<see cref="WorkStation.Frameworks.EasyBus.DefaultServer"/>）
        /// </summary>
        /// <param name="server">监听服务器对象</param>
        /// <returns></returns>
        IBus SetupServer(IServer server = null);
    }
}
